from os import access,listdir,F_OK,W_OK
from os.path import isdir,isfile
from hashlib import new,algorithms_available
from argparse import ArgumentParser,RawTextHelpFormatter


def check_correct_path(args):
   if access(args.PATH, F_OK):
      check_for_path_existence(args)
   else:
      print("The specified path does not exist")



def check_for_path_existence(args):
   if access(args.PATH, W_OK):
      switch_hash_file_or_dir(args)
   else:
      print("The program could not get read access file")



def switch_hash_file_or_dir(args):
   if isfile(args.PATH):
      hash_file(args)
   else:
      hash_dir(args)




#dir processing
def hash_dir(args):
   check_empty_dir(args)




def check_empty_dir(args):
   byte = b""
   if len(listdir(args.PATH)):
      byte += read_and_concat_all_files_in_directory_to_one_file(args.PATH, byte)
      get_hashsum(args, byte)
   else:
      print("Dirrectory is EMPTY!")




def read_and_concat_all_files_in_directory_to_one_file(path, byte):
   byte_with_one_file  = b""
   for link in listdir(path):
      if isdir(f"{path}/{link}"):
         byte_with_one_file += read_and_concat_all_files_in_directory_to_one_file(f"{path}/{link}", byte_with_one_file)
      else:
          byte_with_one_file += read_file(f"{path}/{link}")   
   return byte_with_one_file

#file processing
def hash_file(args):
   get_hashsum(args, read_file(args.PATH) )




#general purpose functions
def read_file(path):
   file = open(f"{path}","rb")
   get_into  = file.read()
   file.close()
   return get_into



def get_hashsum(args,get_into):
   try:
      method = new(f"{args.METHOD}")
      method.update(get_into)
      hashsum = method.hexdigest()
      check_where_to_display_result(args,hashsum)
   except ValueError:
      print("Use hashsum -h/--help to see all supported methods!")





def check_where_to_display_result(args,hashsum):
   if args.OUT:
      write_hash_in_file(hashsum)
   else:
      print(hashsum)



def write_hash_in_file(hashsum):
   file = open("hash.txt","a+")
   file.write(f"{hashsum}\n")
   file.close()
#end general purpose functions



def main():

#init_parser
   parser = ArgumentParser(
      formatter_class=RawTextHelpFormatter,
      description=f"\tThis script allows you to generate a hash. Can work with a file/directory\n\n\t\tAll supported methods:\n\n{', '.join(sorted(list(algorithms_available)))}\n\n Example: hashsum.py [path] [method] [out]")

#add argument
   parser.add_argument("PATH", type=str, help="Accepts the path to a file or directory")
   parser.add_argument("METHOD", type=str, help="Sets the encryption method")
   parser.add_argument("OUT", type=int, help="Get number type int, where 0 - out result to terminal, 1 - out result to file hash.txt")

   args = parser.parse_args()
#end init parser
   check_correct_path(args)



if __name__ == "__main__":
   main()
